package com.pan.service.aspect;


import com.pan.dao.category.CategorySelectDao;
import com.pan.dao.categoryHistory.CategoryHistoryDao;
import com.pan.entity.Category;
import com.pan.entity.OperationCategoryHistory;
import com.pan.entity.Result;
import com.pan.excep.enume.ErrorCode;
import com.pan.excep.error.ServiceException;
import com.pan.tools.RedisTools;
import com.pan.vo.CategoryCreateVo;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.sql.Timestamp;
import java.util.Arrays;

@Aspect
@Component
public class CategoryAspect {

    @Resource
    private CategoryHistoryDao categoryHistoryDao;

    @Resource
    private CategorySelectDao categorySelectDao;

    @Resource
    private RedisTools redisTools;

    @Pointcut("execution(public *  com.pan.service.impl.CategoryServiceImpl.*Child(Long))")
    public void childCut(){}


    @Pointcut("execution(public * com.pan.service.impl.CategoryServiceImpl.insert(..))")
    public void insertCut(){}

    @Pointcut("execution(public *  com.pan.service.impl.CategoryServiceImpl.update(..))")
    public void updateCut(){}


    @Around("updateCut() && args(adminTicket,id,updateValue,updateName)")
    @Order(2)
    public Result update(ProceedingJoinPoint pjp,String adminTicket,Long id,Object updateValue,String updateName){

        if (!Arrays.stream(CategoryCreateVo.class.getDeclaredFields())
                .filter(f -> f.getName().equals(updateName))
                .findAny().isPresent()) {
            throw  new ServiceException(403,"updateName不存在");
        }
        Category category = categorySelectDao.selectById(id);
        if (category==null){
            throw  new ServiceException(ErrorCode.NOT_FOUND);
        }
        Result result = null;
        try {
            result = (Result) pjp.proceed();
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }
        if (result!=null&&result.getCode()==200){
            Result<Object> resultAdminId = redisTools.hget("admin:"+adminTicket,"id");
            Long adminId = (Long) resultAdminId.getData();
            String operation = "update "+updateName+":"+updateValue;
            Timestamp nowTime = new Timestamp(System.currentTimeMillis());
            OperationCategoryHistory categoryHistory = new OperationCategoryHistory();
            categoryHistory.setAdminId(adminId)
                    .setCategoryId(id)
                    .setUpdateTime(nowTime)
                    .setCategoryName(category.getName())
                    .setOperation(operation);
            categoryHistoryDao.insert(categoryHistory);
        }
        return result;
    }


    @Before("insertCut()||updateCut()")
    @Order(1)
    public void checkLogin(JoinPoint joinPoint){
        String adminTicket = (String) joinPoint.getArgs()[0];
        Result<Boolean> result = redisTools.exists("admin:"+adminTicket);
        if (!result.getData()){
            throw new ServiceException(ErrorCode.NOT_LOGIN);
        }
    }

    @Order(2)
    @Around("insertCut() && args( adminTicket, categoryCreateVo)")
    public Result insertAround(ProceedingJoinPoint pjp,String  adminTicket, CategoryCreateVo categoryCreateVo){
        Result result;
        try {
            result = (Result) pjp.proceed();
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }
        if (result!=null&&result.getCode()==200){
            Long adminId = Long.parseLong((String) redisTools.hget("admin:"+adminTicket,"id").getData());
            Timestamp nowTime = new Timestamp(System.currentTimeMillis());
            OperationCategoryHistory categoryHistory = new OperationCategoryHistory();
            categoryHistory.setCategoryId((Long) result.getData())
                    .setAdminId(adminId)
                    .setCategoryName(categoryCreateVo.getName())
                    .setUpdateTime(nowTime)
                    .setOperation("insert");
            categoryHistoryDao.insert(categoryHistory);
        }
        return result;
    }


    @Before("childCut()")
    @Order(2)
    public void checkChildNull(JoinPoint joinPoint){
        Long id = (Long) joinPoint.getArgs()[0];
        Category category = categorySelectDao.selectById(id);
        if (category==null){
            throw  new ServiceException(ErrorCode.NOT_FOUND);
        }
    }



}
